package com.grace.cms.search.lucene.document;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;

import com.grace.cms.common.enums.ArticleTypeEnums;

import org.apache.lucene.document.StringField;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.StoredField;

/**
 * 文章文档实体类
 */
public class ArticleDocument implements SearchableDocument {

    public static final String ID = "id";
    public static final String TITLE = "title";
    public static final String CONTENT = "content";
    public static final String AUTHOR = "author";
    public static final String TYPE = "type";
    public static final String ARTICLE_TYPE = ArticleTypeEnums.ARTICLE.name();
    public static final String PUBLISH_DATE = "publishDate";
    public static final String TAGS = "tags";
    public static final String STATUS = "status";
    public static final String VIEW_COUNT = "viewCount";
    public static final String COVER_IMAGE = "coverImage";
    public static final String SUMMARY = "summary";

    private String id;
    private String title;
    private String content;
    private String author;
    private long publishDate;
    private List<String> tags;
    private String status;
    private long viewCount;
    private String articleType;
    private String coverImage;
    private String summary;

    private Map<String, Object> dynamicFields = new HashMap<>();

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public long getPublishDate() {
        return publishDate;
    }

    public void setPublishDate(long publishDate) {
        this.publishDate = publishDate;
    }

    public List<String> getTags() {
        return tags;
    }

    public void setTags(List<String> tags) {
        this.tags = tags;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public long getViewCount() {
        return viewCount;
    }

    public void setViewCount(long viewCount) {
        this.viewCount = viewCount;
    }

    public String getCoverImage() {
        return coverImage;
    }

    public void setCoverImage(String coverImage) {
        this.coverImage = coverImage;
    }

    public String getArticleType() {
        return articleType;
    }

    public void setArticleType(String articleType) {
        this.articleType = articleType;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public Map<String, Object> getDynamicFields() {
        return dynamicFields;
    }

    public void setDynamicFields(Map<String, Object> dynamicFields) {
        this.dynamicFields = dynamicFields;
    }

    /**
     * 将ArticleDocument转换为Lucene Document
     * 
     * @return Document
     */
    public Document toDocument() {
        Document document = new Document();
        document.add(new StringField(ID, id, Field.Store.YES));
        document.add(new TextField(TITLE, title, Field.Store.YES));
        document.add(new TextField(CONTENT, content, Field.Store.YES));
        document.add(new TextField(AUTHOR, author, Field.Store.YES));
        document.add(new StringField(TYPE, "article", Field.Store.YES));// 添加文档类型标识
        document.add(new LongPoint(PUBLISH_DATE, publishDate));
        document.add(new StoredField(PUBLISH_DATE, publishDate));
        document.add(new NumericDocValuesField(PUBLISH_DATE, publishDate));  // 用于排序
        document.add(new TextField(TAGS, String.join(",", tags), Field.Store.YES));
        document.add(new StringField(STATUS, status, Field.Store.YES));
        document.add(new LongPoint(VIEW_COUNT, viewCount));
        document.add(new StoredField(VIEW_COUNT, viewCount));
        document.add(new NumericDocValuesField(VIEW_COUNT, viewCount));  // 用于排序
        document.add(new StringField(COVER_IMAGE, coverImage, Field.Store.YES));
        document.add(new StringField(ARTICLE_TYPE, articleType, Field.Store.YES));
        document.add(new TextField(SUMMARY, summary, Field.Store.YES));
        // 动态字段处理
        for (Map.Entry<String, Object> entry : dynamicFields.entrySet()) {
            document.add(new TextField(entry.getKey(), entry.getValue().toString(), Field.Store.YES));
        }
        return document;
    }

    /**
     * 从Lucene Document转换为ArticleDocument
     * 
     * @param document Lucene Document
     * @return ArticleDocument
     */
    public static ArticleDocument fromDocument(Document document) {
        ArticleDocument articleDocument = new ArticleDocument();
        articleDocument.setId(document.get(ID));
        articleDocument.setTitle(document.get(TITLE));
        articleDocument.setContent(document.get(CONTENT));
        articleDocument.setAuthor(document.get(AUTHOR));
        articleDocument.setPublishDate(Long.parseLong(document.get(PUBLISH_DATE)) );
        articleDocument.setTags(Arrays.asList(document.get(TAGS).split(",")));
        articleDocument.setStatus(document.get(STATUS));
        articleDocument.setViewCount(Integer.parseInt(document.get(VIEW_COUNT)));
        articleDocument.setCoverImage(document.get(COVER_IMAGE));
        articleDocument.setArticleType(document.get(ARTICLE_TYPE));
        articleDocument.setSummary(document.get(SUMMARY));
        return articleDocument;
    }

}